﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Clandestine.Conversations;
using System.Threading;
using Clandestine;
using Clandestine.Entities;

namespace JibberJabber
{
    public class Preview
    {
        private bool running = true;
        private bool convRunning = true;
        private Thread convoThread = null;

        public PreviewBackground Background;

        private Mutex pauseMutex = new Mutex();

        public Preview()
        {
            Clandestine.Program.Running = true;

            bool wecoolbrah = false;

            Thread renderThread = new Thread(new ThreadStart(delegate()
            {
                Clandestine.Graphics.Initialise(1, new OpenTkManager());
                Clandestine.Fonts.Initialise();
                Clandestine.Keyboard.Initialise();
                Clandestine.Ticker.Initialise();
                Background = new PreviewBackground();
                wecoolbrah = true;
                bool frmMainHasBeenVisible = false;
                while (running)
                {
                    pauseMutex.WaitOne();

                    Clandestine.Graphics.Render();
                    if (Program.frmMain != null && Program.frmMain.Visible)
                        frmMainHasBeenVisible = true;
                    if (!Clandestine.Program.Running || (frmMainHasBeenVisible && !Program.frmMain.Visible))
                        running = false;

                    pauseMutex.ReleaseMutex();
                }
                if (convoThread != null && convRunning)
                    convoThread.Abort();
                Clandestine.Program.Running = false;
                Exit();
                Clandestine.Ticker.Deinitialise();
                Clandestine.Keyboard.Deinitialise();
                Clandestine.Graphics.Deinitialise();
            }));
            renderThread.Start();

            // Block for init completion.
            while (!wecoolbrah)
                Thread.Sleep(50);
        }

        public void Pause()
        {
            pauseMutex.WaitOne();
        }

        public void Resume()
        {
            pauseMutex.ReleaseMutex();
        }

        public void ClearFuckingEverything()
        {
            // Not using background.reload() technique,
            // because Levels are way too slow atm :(
            // lots of animatedsprite activity seems to be going on...

            IEnumerable<Sprite> whitelistedSprites = Background.TryGetSprites();

            lock (Graphics.Renderables)
                foreach (Renderable r in Graphics.Renderables.ToArray())
                    if (!(r is Sprite) || !whitelistedSprites.Contains(((Sprite)r)))
                        r.Dispose();

            //Background.Reload();
        }

        private void start(Conversation c)
        {
            convoThread = new Thread(new ThreadStart(delegate()
            {
                c.Start();
                
                convRunning = false;
            }));
            convoThread.Start();
        }

        public void ChangeConversation(Conversation c)
        {
            if (convoThread != null)
            {
                convoThread.Abort();
                convoThread = null;
                // idk what to do next tbh
            }

            start(c);
        }

        private bool exitrun = false;
        public void Exit()
        {
            if (exitrun)
                return;
            exitrun = true;

            running = false;

            while (Clandestine.Program.Running
                || (convoThread != null && convoThread.ThreadState != ThreadState.Stopped && convRunning))
                Thread.Sleep(50);
        }
    }
}
